#include "httputil.h"

#define RFC1123_STRFTIME "%a, %d %b %Y %H:%M:%S GMT"

const char* http_mkrfc1123(char* buf, size_t size, time_t t)
{
#if (TARGET_OS == OS_WIN)
    struct tm* gmt = gmtime(&t);
#else
    struct tm gmt_buf, *gmt = gmtime_r(&t, &gmt_buf);
#endif

    buf[0] = 0;

    if (gmt != NULL)
        strftime(buf, size - 1, RFC1123_STRFTIME, gmt);
    return (buf);
}

static unsigned char enc_tab[] = "0123456789ABCDEF";
char* http_gb2312_url_encode(const char* str)
{
    int i, j, len, tmp_len;
    unsigned char* tmp;

    len = (int)strlen(str);
    tmp_len = len;

    tmp = (unsigned char*)malloc(len + 1);

    for (i = 0, j = 0; i < len; i++, j++) {
        tmp[j] = (unsigned char)str[i];
        if (!isalnum(tmp[j]) && strchr("_-.", tmp[j]) == NULL) {
            tmp_len += 3;
            tmp = (unsigned char*)realloc(tmp, tmp_len);
            tmp[j++] = '%';
            tmp[j++] = enc_tab[(unsigned char)str[i] >> 4];
            tmp[j] = enc_tab[(unsigned char)str[i] & 0x0F];
        }
    }

    tmp[j] = '\0';
    return (char*)tmp;
}

static unsigned char dec_tab[256] = {
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6,  7,  8,  9,  0,  0,  0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
char* http_gb2312_url_decode(const char* str)
{
    char* tmp;
    int i, len, pos = 0;

    len = (int)strlen(str);
    tmp = (char*)malloc(len + 1);
    for (i = 0; i < len; i++) {
        /* If we found a '%' character, then the next two are
         * the character hexa code. Converting a hexadecimal
         * code to their decimal is easy: The first character
         * needs to be multiplied by 16 ( << 4 ), and the
         * another one we just get the value from hextable variable
         */
        /*
        if (str[i] == '+')
        tmp[pos] = ' ';
        else */
        if (str[i] != '%')
            tmp[pos] = str[i];
        else if (i + 2 >= len) { /* check boundary */
            tmp[pos++] = '%';    /* keep it */
            if (++i >= len)
                break;
            tmp[pos] = str[i];
            break;
        } else if (isalnum(str[i + 1]) && isalnum(str[i + 2])) {
            tmp[pos] = (dec_tab[(unsigned char)str[i + 1]] << 4) + dec_tab[(unsigned char)str[i + 2]];
            i += 2;
        } else
            tmp[pos] = str[i];

        pos++;
    }

    tmp[pos] = '\0';
    return tmp;
}
